#ifndef POINT3_H_
#define POINT3_H_

#include <cmath>
#include <sstream>

#include "Object.h"

namespace OOInterface {

/**
 *
 *
 */

template< class T>
class Point3 : public Object
{
public:
	Point3() : _x(0), _y(0), _z(0) {}
	Point3(T x, T y, T z) : _x(x), _y(y), _z(z) {}
	Point3( const Point3<T>& p ) : _x(p._x), _y(p._y), _z(p._z) {}
	Point3<T>& operator=( const Point3<T>& rhs ) { _x = rhs._x; _y = rhs._y; _z = rhs._z; return *this; }
	virtual ~Point3() {}

	inline void setX( T x ) { _x = x; }
	inline void setY( T y ) { _y = y; }
	inline void setZ( T z ) { _z = z; }

	inline T getX() const { return _x; }
	inline T getY() const { return _y; }
	inline T getZ() const { return _z; }

	T distanceTo( const Point3<T>& p ) const
	{
		return std::sqrt(std::pow( (p._x - _x ), 2) + std::pow((p._y - _y), 2) + std::pow( (p._z -_z), 2));
	}

	virtual std::string toString() const
	{
		std::ostringstream str;
		str << "Point3f: ( " << _x << ", " << _y << ", " << _z << " )";
		return str.str();
	}

private:
	T _x, _y, _z;
};

typedef Point3<float> Point3f;
typedef Point3<int> Point3i;
typedef Point3<double> Point3d;

}

#endif /*POINT3_H_*/
